package user

import (
	"context"
	"log"
	"net/http"
)

// 上下文键
type contextKey string

const (
	// UserIDKey 用户ID的上下文键
	UserIDKey contextKey = "user_id"
	// SessionKey 会话的上下文键
	SessionKey contextKey = "session"
)

// AuthMiddleware 身份验证中间件
type AuthMiddleware struct {
	service Service
}

// NewAuthMiddleware 创建新的身份验证中间件
func NewAuthMiddleware(service Service) *AuthMiddleware {
	return &AuthMiddleware{service: service}
}

// Authenticate 验证用户身份
func (m *AuthMiddleware) Authenticate(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 从请求头中获取会话ID
		sessionID := extractSessionID(r)
		if sessionID == "" {
			respondWithError(w, http.StatusUnauthorized, "未提供有效的会话ID", 1003)
			return
		}

		// 获取用户状态
		status, err := m.service.GetUserStatus(sessionID)
		if err != nil {
			log.Printf("身份验证失败: %v", err)
			respondWithError(w, http.StatusUnauthorized, "未登录或会话已过期", 1003)
			return
		}

		// 将用户ID和会话信息添加到请求上下文
		ctx := context.WithValue(r.Context(), UserIDKey, status.UserID)
		ctx = context.WithValue(ctx, SessionKey, sessionID)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

// GetUserIDFromContext 从上下文中获取用户ID
func GetUserIDFromContext(ctx context.Context) (int64, bool) {
	id, ok := ctx.Value(UserIDKey).(int64)
	return id, ok
}

// GetSessionFromContext 从上下文中获取会话ID
func GetSessionFromContext(ctx context.Context) (string, bool) {
	session, ok := ctx.Value(SessionKey).(string)
	return session, ok
}
